package com.example.flight.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.flight.common.BuyException;
import com.example.flight.dao.FlightInformationDao;
import com.example.flight.entity.FlightInformationEntity;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;


import com.example.flight.dao.OrderDao;
import com.example.flight.entity.OrderEntity;
import com.example.flight.service.OrderService;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;


@Service("orderService")
public class OrderServiceImpl extends ServiceImpl<OrderDao, OrderEntity> implements OrderService {
    @Autowired
    OrderDao orderDao;
@Autowired
    FlightInformationDao flightInformationDao;

    @Override
    public List<OrderEntity> listByUid(String uid) {
        LambdaQueryWrapper<OrderEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrderEntity::getUid, uid);
        List<OrderEntity> orders = orderDao.selectList(queryWrapper);

        addFlightInformation(orders);

        return  orders;
    }

    private void addFlightInformation(List<OrderEntity> orders) {
        for (OrderEntity order : orders) {
            FlightInformationEntity flightInformation = flightInformationDao.selectById(order.getFid());
            order.setDepartureTime(flightInformation.getDepartureTime());
            order.setFlightNum(flightInformation.getFlightNum());
            order.setDeparture(flightInformation.getDeparture());
        }
    }


    @Override
    public boolean buy(OrderEntity order) throws BuyException {
        //确定type
        //查余票>0
        //余票-1
        //save order
        System.out.println(order);
        try {
            FlightInformationEntity flightInformation = flightInformationDao.selectById(order.getFid());
            if ("经济舱".equals(order.getClassType())) {
                if (flightInformation.getEconomyClassAvailable() <= 0) return false;
                buyEconomyClass(order, flightInformation);
            }
            if ("商务舱".equals(order.getClassType())) {
                if (flightInformation.getBusinessClassAvailable() <= 0) return false;
                buyBusinessClass(order, flightInformation);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BuyException();
        }

        return true;
    }

    @Override
    public List<OrderEntity> listByIDNum(String identityNumber) {
        LambdaQueryWrapper<OrderEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrderEntity::getIdentityNumber, identityNumber);
        List<OrderEntity> orders = orderDao.selectList(queryWrapper);
        addFlightInformation(orders);
        return  orders;
    }

    @Transactional(propagation = Propagation.REQUIRED,isolation= Isolation.READ_COMMITTED,rollbackFor = Exception.class)
    public void buyEconomyClass(OrderEntity order, FlightInformationEntity flightInformation) throws Exception {
        try {
            flightInformation.setEconomyClassAvailable(flightInformation.getEconomyClassAvailable() - 1);
            flightInformationDao.updateById(flightInformation);
            orderDao.insert(order);
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚失误
            throw new Exception(e);
        }
    }


    @Transactional(propagation = Propagation.REQUIRED,isolation= Isolation.READ_COMMITTED,rollbackFor = Exception.class)
    public  void buyBusinessClass(OrderEntity order, FlightInformationEntity flightInformation) throws Exception {
        try {
            flightInformation.setBusinessClassAvailable(flightInformation.getBusinessClassAvailable() - 1);
            flightInformationDao.updateById(flightInformation);
            orderDao.insert(order);
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚失误
            throw new Exception(e);
        }
    }
}

